from sys import argv
from xml.dom import minidom  
from Board import *

class LogicalError(Exception):
    def __init__(self, string):
	self.msg=string

    def __str__(self):
	return repr(self.msg)


def ExtractTile(t, board):
    ret = Tile()

    x=t.getAttribute('x')
    y=t.getAttribute('y')
    color=t.getAttribute('color')

    text = t.getElementsByTagName("text")
    if(len(text)>0):
	text = text[0].childNodes[0]
	text = text.nodeValue
	ret.setText(text)

    action = t.getElementsByTagName("action")
    if(len(action)>0):
	action = action[0]
	type = action.getAttribute("type")	
	value = action.getAttribute("value")
	if(value == ''):
	    ret.setAction(type)
	else:
	    ret.setAction(type, int(value))

    condition = t.getElementsByTagName("condition")
    if(len(condition)>0):
	condition = condition[0]
	group = condition.getAttribute("group")
	if(not board.groups.has_key(group)):	    
	    raise LogicalError("Error: Unexistent Group '"+ group.encode("utf-8") + "' this group must be defined in the groups element.")
	ret.setCond(group)

    ret.x = x
    ret.y = y
    ret.color = color

    return  ret

def parse(boardXML):
    boardRet = Board()

    #teoricamente tah tudo ok. vamos construir o objeto
    xmldoc = minidom.parse(argv[1])
    #pronto! o xml ta todo dentro de xmldoc! que beleza.

#    root = xmldoc.childNodes[0];
    board = xmldoc.getElementsByTagName("board")[0];
    canvas = board.getElementsByTagName("canvas")[0]

    background = xmldoc.getElementsByTagName("background")[0];
    boardRet.bg = background.getAttribute("path")
    boardRet.color = background.getAttribute("color")

    images = board.getElementsByTagName("image")
    boardRet.images=[]
    for image in images:
        p=image.getAttribute("path")
        x=image.getAttribute("x")
        y=image.getAttribute("y")
        h=image.getAttribute("height")
        w=image.getAttribute("width")
        boardRet.images.append((p,x,y,h,w))

    tiles = canvas.getElementsByTagName("tiles")[0]
    tile = tiles.getElementsByTagName("tile");

    groups = board.getElementsByTagName("groups")
    if(len(groups) != 0):
	group = groups[0].getElementsByTagName("group")
	for g in group:
	    groupId = g.getAttribute("value")
	    quizzes = Quizzes(groupId)
	    quiz = g.getElementsByTagName("quiz")
	    for q in quiz:
		allL=[]
		question = q.getElementsByTagName("question")[0]
		qStr = question.getAttribute("value");
		right = q.getElementsByTagName("correct")[0]
		rStr = right.getAttribute("value")
		allL.append(rStr)
		wrongs = q.getElementsByTagName("wrong")
		for w in wrongs:
		    wStr = w.getAttribute("value");
		    allL.append(wStr)
		quiz = Quiz (qStr, rStr, allL)
		quizzes.quizzes.append(quiz)
	    boardRet.groups[groupId]=quizzes

    for t in tile:
	id = t.getAttribute("id")
	if(boardRet.tiles.has_key(id)):
	    raise LogicalError("Error: Duplicated Id: '"+ id.encode("utf-8") + "' tile ids must be uniques")
	else:
	    boardRet.tiles[id] = ExtractTile(t, boardRet)

    pawns = board.getElementsByTagName("pawns")[0]
    players = pawns.getElementsByTagName("player")
    boardRet.pawns = {}
    for player in players:
        id=player.getAttribute("id");
        path=player.getAttribute("path");
        boardRet.pawns[id]=path

    path = board.getElementsByTagName("path")[0]
    links = path.getElementsByTagName("link")
    for link in links:
	cu = link.getAttribute("current")
	ne = link.getAttribute("next")
	if(boardRet.path.has_key(cu)):
	    raise LogicalError("Error: Path leaving " + cu.encode("utf-8") + " more than one time")
	boardRet.path[cu]=ne
    boardRet.PostProcess();
    return boardRet


if  __name__ == "__main__":
    if ( len(argv) != 3):
        print "usage:\n   XMLValidator [xml file] [xsd file]"
        exit(1)
    print Loader(argv[1],argv[2])

def Loader(xml, xsd):

    try:
	import XMLValidator
    except:
	print 'Could not load the lxml lib, will NOT validate.Please Fix this'
        board =  parse(xml)
	return board

    reader = XMLValidator.Reader(xml,xsd)
    try:
        reader.validate()
    #tratar as excecoes de acordo    
    except XMLValidator.ValidationException as error:
	print "Erro de validacao"
	print error
	exit(1)
    except IOError as error:
	print "IO Error"
	print error
	exit(1)
    board =  parse(xml)
    return board

